import { Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { Hero } from './entities/hero.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { GetHeroListDto } from './dto/get-hero-list.dto';
import { CreateHeroDto, DeleteHeroDto, UpdateHeroDto } from './dto/hero.dto';

@Injectable()
export class HeroService {
  constructor(
    @InjectRepository(Hero)
    private readonly heroRepository: Repository<Hero>,
  ) {}

  async findOne(id: number) {
    return this.heroRepository.findOne({
      where: {
        id,
      },
    });
  }

  async find(dto: GetHeroListDto) {
    const {
      pageNum,
      pageSize,
      name,
      landingDate,
      versionStrength,
      heroLocation,
    } = dto;
    const take = pageSize || 10;
    const skip = ((pageNum || 1) - 1) * take;

    // 构建查询条件
    const query = this.heroRepository.createQueryBuilder('hero');

    // 添加筛选条件，只处理有值的字段
    if (name) {
      query.andWhere('hero.name LIKE :name', { name: `%${name}%` });
    }

    // 处理 landingDate，查询在 landingDate 之后的数据
    if (landingDate) {
      // 将字符串转换为 Date 对象
      const date = new Date(landingDate);
      // 设置为当天的开始时间，确保查询包含指定日期的所有数据
      date.setHours(0, 0, 0, 0);

      // 使用 >= 查询，返回指定日期及之后的所有数据
      query.andWhere('hero.landingDate >= :landingDate', { landingDate: date });
    }

    if (versionStrength) {
      query.andWhere('hero.versionStrength = :versionStrength', {
        versionStrength,
      });
    }

    if (heroLocation && heroLocation.length > 0) {
      // 简单直接的方式：使用JSON_SEARCH函数检查heroLocation数组中是否包含任一指定的值
      const conditions = [];
      
      // 为每个要查询的位置值构建一个条件
      for (const location of heroLocation) {
        // 确保location是字符串并进行适当的转义，避免SQL注入
        const safeLocation = String(location).replace(/'/g, "''");
        // JSON_SEARCH函数用于查找JSON数组中是否包含指定的字符串值
        conditions.push(`JSON_SEARCH(hero.heroLocation, 'one', '${safeLocation}') IS NOT NULL`);
      }
      
      // 将所有条件用OR连接，只要匹配任一条件就返回该条目
      const whereClause = conditions.join(' OR ');
      query.andWhere(whereClause);
    }

    // 分页查询
    const [data, total] = await query.take(take).skip(skip).getManyAndCount();

    // 返回结果，包括数据列表和分页信息
    return {
      data,
      pageNum,
      pageSize,
      total,
    };
  }

  async create(dto: CreateHeroDto) {
    const hero = this.heroRepository.create({
      ...dto,
      posters: dto.posters || [],
    });

    const save = await this.heroRepository.save(hero);

    return !!save;
  }

  async update(dto: UpdateHeroDto) {
    const hero = await this.findOne(dto.id);
    if (!hero) {
      return false;
    }
    const save = await this.heroRepository.save({
      ...hero,
      ...dto,
      posters: dto.posters || [],
    });
    return !!save;
  }

  async delete(dto: DeleteHeroDto) {
    const hero = await this.findOne(dto.id);
    if (hero) {
      await this.heroRepository.remove(hero);
    }
    return !!hero;
  }
}
